#include<sys/types.h>
#include<sys/stat.h>
#include <fcntl.h>

#include "device/context.h"
#include "device/ops.h"


RCStatus CreateFIFO(const char* name, mode_t mode, int flags, int* fd)
{
    int ret = mkfifo(name, mode);
    if (ret < 0) {
        return RC_MKFIFO_FAILED;
    }
    *fd = open(name, flags);
    if (fd < 0) {
        return RC_OPEN_FIFO_FAILED;
    }
    return RC_SUCCESS;
}

RCStatus CreateExecThread(Context* context)
{

}

RCStatus ContextCreate(Context** context)
{
    *context = (Context*)MemAlloc(sizeof(Context));
    if (context == NULL) {
        return RC_MALLOC_FAILED;
    }
    (void)memset(context->buff, 0, sizeof(Context));

    RC_STATUS ret = CreateFIFO(COMMAND_FIFO, 0777, O_RDONLY, &(context->recvFIFO));
    if (ret != RC_SUCCESS) {
        goto ERROR_CMD_FIFO_FAILED;
    }

    ret = CreateFIFO(ACK_FIFO, 0777, O_WRONLY, &(context->sendFIFO));
    if (ret != RC_SUCCESS) {
        goto ERROR_SND_FIFO_FAILED;
    }
    size_t i = 0;
    int pc = 0;
    for (i = 0; i < THREAD_POOL_SIZE; ++i) {
        ret = CreateExecThread(&(context->tpool[i]));
        if (ret != RC_SUCCESS) {
            goto ERROR_CREATE_EXEC_THREAD;
        }
    }

    return RC_SUCCESS;

ERROR_CREATE_EXEC_THREAD:
    int e = 0;
    for (e = 0; e < i; ++e) {
        ExecThreadDestroy(&(context->tpool[i]));
    }

ERROR_TASK_LIST_CREATE_FAILED:
    for (i = 0; i < THREAD_POOL_SIZE; ++i) {
        context->tpool[i].taskQue = TaskListCreate(RC_TASK_LIST_SIZE);
        if (!context->tpool[i].taskQue) {
            TaskListDestroy(&(context->tpool[i].taskQue));
            *(context->tpool[i].taskQue) = NULL;
        }
        pthread_join(context->tpool[i].tid);
    }

ERROR_SND_FIFO_FAILED:
    unlink(COMMAND_FIFO);

ERROR_CMD_FIFO_FAILED:
    MemFree(*context);
    *context = NULL;

    return ret;
}

void ContextDestroy(Context** context)
{

}